package com.autonavi.yunda.yunji.service;

import com.autonavi.yunda.yunji.common.exception.AmapException;
import com.autonavi.yunda.yunji.common.exception.AmapExceptionCode;
import com.autonavi.yunda.yunji.common.utils.JsonUtils;
import com.autonavi.yunda.yunji.common.utils.http.HttpClient;
import com.autonavi.yunda.yunji.common.utils.http.vo.HttpResponse;
import com.autonavi.yunda.yunji.core.config.ApplicationEnvConfig;
import com.autonavi.yunda.yunji.service.model.FactoryResponse;
import com.autonavi.yunda.yunji.service.model.FactoryUserDetail;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author cizhong.wcs
 * @date 2023/9/8 14:08
 */
@Slf4j
@Component
public class FactoryUserService {
    @Value("${factory.auth.host}")
    private String factoryAuthHost = "http://factory-permission-server.amap.test";
    static HttpClient httpClient = new HttpClient();
    private static Cache<String, FactoryUserDetail> FACTORY_USER_INFO_CACHE
            = CacheBuilder.newBuilder().expireAfterAccess(1L, TimeUnit.HOURS).build();
    @Resource
    private BucUserService bucUserService;
    @Resource
    private ApplicationEnvConfig applicationEnvConfig;


    public Long getCurrentUserBdId() {
        try {
            return fetchUserInfo(bucUserService.getCurEmployeeId()).bdId;
        } catch (Exception e) {
            log.warn("获取当前用户bdId失败", e);
        }
        return null;
    }

    public FactoryUserDetail fetchUserInfo(String workNo) {
        if (applicationEnvConfig.isDev() || applicationEnvConfig.isDaily()) {
            return fetchUserInfoFromCache(workNo);
        } else {
            return fetchUserInfoFromFactory(workNo);
        }
    }

    public FactoryUserDetail fetchUserInfoFromCache(String workNo) {
        FactoryUserDetail userDetail = FACTORY_USER_INFO_CACHE.getIfPresent(workNo);
        if (null != userDetail) {
            return userDetail;
        }
        userDetail = fetchUserInfoFromFactory(workNo);
        if (userDetail != null) {
            FACTORY_USER_INFO_CACHE.put(workNo, userDetail);
        }
        return userDetail;
    }

    public void invalidUserInfoCache() {
        FACTORY_USER_INFO_CACHE.invalidateAll();
    }

    public FactoryUserDetail fetchUserInfoFromFactory(String workNo) {
        long stime = System.currentTimeMillis();
        workNo = transferToFactoryEmployeeId(workNo);
        String url = factoryAuthHost + "/user/detail?code=yunpro-api&workNo=" + workNo;
        HttpResponse httpResponse = httpClient.get(url, null);
        FactoryResponse<FactoryUserDetail> response = JsonUtils.from(httpResponse.getBody(), new TypeReference<>() {
        });
        log.info("fetchUserInfoFromFactory 执行时长 {} 毫秒", (System.currentTimeMillis() - stime));
        if (response.getCode().equals(0)) {
            return response.getData();
        } else if (response.getCode().equals(4006)) {
            throw new AmapException(AmapExceptionCode.COMMON_SERVER_WARN, "用户不存在,请联系管理员添加用户");
        } else {
            throw new AmapException(AmapExceptionCode.COMMON_SERVER_ERROR, "未知错误:" + JsonUtils.toString(response));
        }
    }

    public boolean checkPermission(String workNo, String permissionCode) {
        try {
            FactoryUserDetail factoryUserDetail = fetchUserInfo(workNo);
            if (factoryUserDetail == null) {
                return false;
            }
            return factoryUserDetail.resources
                    .stream().map(r -> r.code)
                    .collect(Collectors.toSet())
                    .contains(permissionCode);
        } catch (Exception e) {
            log.warn("checkPermission error");
            return false;

        }

    }

    /**
     * 特殊逻辑，小于10万的工号补齐前面的0，凑够6位
     * <p>
     * 集团BUC返回的工号长度如果小于6，则会抛弃前面的0
     */
    public String transferToFactoryEmployeeId(String bucEmployeeId) {
        StringBuilder employeeId = new StringBuilder();
        int STANDARD_EMPLOYEE_ID_LEN = 6;
        if (bucEmployeeId.length() < STANDARD_EMPLOYEE_ID_LEN) {
            int size = bucEmployeeId.length();
            while (size < STANDARD_EMPLOYEE_ID_LEN) {
                employeeId.append("0");
                size++;
            }
            employeeId.append(bucEmployeeId);
        } else {
            employeeId.append(bucEmployeeId);
        }
        return employeeId.toString();
    }

}
